#ifndef _MD5_H_
#define _MD5_H_

/* POINTER defines a generic pointer type */
typedef unsigned char *POINTER;

/* UINT2 defines a two byte word */
typedef unsigned short int UINT2;

/* UINT4 defines a four byte word */
typedef unsigned long int UINT4;

//#define PROTO_LIST(list) list

/* MD5 context. */
typedef struct _MD5_CTX
{
    UINT4 state[4]; /* state (ABCD) */
    UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
    unsigned char buffer[64]; /* input buffer */
} MD5_CTX;


class Md5
{
public:
	//times: encode times
	static int md5(char *dst,char* src,int times=1);
	static void init(MD5_CTX *);
	static void update(MD5_CTX *, unsigned char *, unsigned int);
	static void final(unsigned char [16], MD5_CTX *);

private:
	static void transform(UINT4 [4], unsigned char [64]);
	static void encode(unsigned char *, UINT4 *, unsigned int);
	static void decode(UINT4 *, unsigned char *, unsigned int);
	static void MD5_memcpy(POINTER, POINTER, unsigned int);
	static void MD5_memset(POINTER, int, unsigned int);
	static void MDTimeTrial(void);
	static void StringAddOne(char *);
};

#endif //_MD5_H_
